package org.jks.controller;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.hibernate.JDBCException;
import org.hibernate.exception.ConstraintViolationException;
import org.jks.config.Config;
import org.jks.constant.Constants;
import org.jks.constant.SysConfig;
import org.jks.model.City;
import org.jks.model.Department;
import org.jks.model.Education;
import org.jks.model.Flight;
import org.jks.model.PoliticalStatus;
import org.jks.model.Position;
import org.jks.model.Role;
import org.jks.model.User;
import org.jks.report.model.ReportUserModel;
import org.jks.request.model.Ids;
import org.jks.request.model.UIUser;
import org.jks.response.model.ActionResult;
import org.jks.response.model.UITable;
import org.jks.service.CityService;
import org.jks.service.RoleService;
import org.jks.service.UserService;
import org.jks.util.DateUtil;
import org.jks.util.ExportUtil;
import org.jks.util.FileUtil;
import org.jks.util.JsonUtil;
import org.jks.util.PrivilegeUtil;
import org.jks.util.ResponseUtil;
import org.jks.util.SimpleCrypto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.mysql.jdbc.MysqlDataTruncation;

@Controller
@RequestMapping("/user")
public class UserController {
	@Autowired
	UserService userService;
	@Autowired
	CityService cityService;
	@Autowired
	RoleService roleService;
	
	@RequestMapping("/add")
	public void add(UIUser uiUser, HttpServletRequest request,
			HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		try {
			String recruitment = "";
			City city = cityService.get(City.class, uiUser.getCityId());
			recruitment = city.getProvince().getName() + " " + city.getName();
			User user = new User();
			user.setBirthday(DateUtil.toDate(uiUser.getBirthday(), "yyyy-MM-dd"));
			user.setUsername(uiUser.getUsername());
			Flight flight = new Flight();
			flight.setId(uiUser.getFlightId());
			user.setFlight(flight);
			String p = SimpleCrypto.encrypt(Constants.MANAGER_PASSWORD, "123456");
			user.setPassword(p);
			user.setRecruitment(recruitment);
			user.setName(uiUser.getName());
			user.setDocumentNumber(uiUser.getDocumentNumber());
			user.setContactNumber(uiUser.getContactNumber());
			Department department = new Department();
			department.setId(uiUser.getDepartmentId());
			user.setDepartment(department);
			Education education = new Education();
			education.setId(uiUser.getEducationId());
			user.setEducation(education);
			user.setHomeAddress(uiUser.getHomeAddress());
			PoliticalStatus politicalStatus = new PoliticalStatus();
			politicalStatus.setId(uiUser.getPoliticalStatusId());
			user.setPoliticalStatus(politicalStatus);
			Position position = new Position();
			position.setId(uiUser.getPositionId());
			user.setPosition(position);
			user.setRecruitment(user.getRecruitment());
//			user.setRFID(uiUser.getRFID());
			user.setSex(uiUser.getSex());
			user.setToPartInTheWorkTime(DateUtil.toDate(uiUser.getToPartInTheWorkTime(), "yyyy-MM-dd"));
			
			Set<Role> temp = new HashSet<Role>();
			for(int i = 0; i < uiUser.getRoleId().length; i++)
			{
				Role role = roleService.get(Role.class, uiUser.getRoleId()[i]);
				role.setPrivileges(null);
				role.setUsers(null);
				temp.add(role);				
			}
			
			user.setRoles(temp);
					
			String defaultHeaderPic = "view/images/default_headpic.png";
			if(!uiUser.getTwoInchPhotos().equals(defaultHeaderPic)){
				FileUtil.moveFile(request.getServletContext(), uiUser.getTwoInchPhotos(), uiUser.getUsername(), false, null);
				defaultHeaderPic = FileUtil.getTargetPath(uiUser.getTwoInchPhotos(), uiUser.getUsername());
			}
			
			user.setTwoInchPhotos(defaultHeaderPic);
			userService.save(user);
			ar.setSuccess(true);
			ar.setData(user);
		}
		catch( MysqlDataTruncation e){
			ar.setMsg(e.getMessage());
		}
		catch( ConstraintViolationException e){
			ar.setMsg("用户名称冲突");
		}
		catch (Exception e) {
			e.printStackTrace();
			ar.setMsg(e.getMessage());
		}
		ResponseUtil.returnJson(response, ar);
	}

	public void add(User user, HttpServletRequest request,
			HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		try {
			userService.save(user);
			ar.setSuccess(true);
			ar.setData(user);
		} catch (Exception e) {
			ar.setMsg(e.getMessage());
		}
		ResponseUtil.returnJson(response, ar);
	}

	@RequestMapping("/delete")
	public void delete(Ids ids, HttpServletRequest request,
			HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		try {
			for(long id : ids.getIds()){
				userService.delete(id);
			}
			ar.setSuccess(true);
		} catch (Exception e) {
			ar.setMsg("删除用户失败（"+e.getMessage()+")");
			e.printStackTrace();
		}
		ResponseUtil.returnJson(response, ar);
	}

	@RequestMapping("/delete/{id}")
	public void delete(@PathVariable long id, HttpServletRequest request,
			HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		try {
			userService.delete(id);
			ar.setSuccess(true);
		} catch (Exception e) {
			ar.setMsg(e.getMessage());
		}
		ResponseUtil.returnJson(response, ar);
	}
	
	public void update(User user, HttpServletRequest request,
			HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		try {
			userService.update(user);
			ar.setSuccess(true);
		}
		catch(Exception e){
			ar.setMsg(e.getMessage());
			e.printStackTrace();
		}
		ResponseUtil.returnJson(response, ar);
	}

	@RequestMapping("/update")
	public void update(UIUser uiUser, HttpServletRequest request,
			HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		try {
			String recruitment = "";
			City city = cityService.get(City.class, uiUser.getCityId());
			recruitment = city.getProvince().getName() + " " + city.getName();
			User user = new User();
			user.setId(uiUser.getId());
			user.setBirthday(DateUtil.toDate(uiUser.getBirthday(), "yyyy-MM-dd"));
			user.setUsername(uiUser.getUsername());
			Flight flight = new Flight();
			flight.setId(uiUser.getFlightId());
			user.setFlight(flight);
			String p = SimpleCrypto.encrypt(Constants.MANAGER_PASSWORD, "123456");
			user.setPassword(p);
			user.setRecruitment(recruitment);
			user.setName(uiUser.getName());
			user.setDocumentNumber(uiUser.getDocumentNumber());
			user.setContactNumber(uiUser.getContactNumber());
			Department department = new Department();
			department.setId(uiUser.getDepartmentId());
			user.setDepartment(department);
			Education education = new Education();
			education.setId(uiUser.getEducationId());
			user.setEducation(education);
			user.setHomeAddress(uiUser.getHomeAddress());
			PoliticalStatus politicalStatus = new PoliticalStatus();
			politicalStatus.setId(uiUser.getPoliticalStatusId());
			user.setPoliticalStatus(politicalStatus);
			Position position = new Position();
			position.setId(uiUser.getPositionId());
			user.setPosition(position);
			user.setRecruitment(user.getRecruitment());
//			user.setRFID(uiUser.getRFID());
			user.setSex(uiUser.getSex());
			user.setToPartInTheWorkTime(DateUtil.toDate(uiUser.getToPartInTheWorkTime(), "yyyy-MM-dd"));
			
			Set<Role> temp = new HashSet<Role>();
			for(int i = 0; i < uiUser.getRoleId().length; i++)
			{
				Role role = roleService.get(Role.class, uiUser.getRoleId()[i]);
				role.setPrivileges(null);
				role.setUsers(null);
				temp.add(role);				
			}
			
			user.setRoles(temp);
			
			String defaultHeaderPic = "view/images/default_headpic.png";
			if(!uiUser.getTwoInchPhotos().equals(defaultHeaderPic)){
				FileUtil.moveFile(request.getServletContext(), uiUser.getTwoInchPhotos(), uiUser.getUsername(), false, null);
				defaultHeaderPic = FileUtil.getTargetPath(uiUser.getTwoInchPhotos(), uiUser.getUsername());
			}
			
			user.setTwoInchPhotos(defaultHeaderPic);
			userService.update(user);
			ar.setSuccess(true);
			ar.setData(user);
		} catch (JDBCException e) {
			ar.setMsg("更新用户失败(" + e.getMessage() + ")");
		}
		catch (Exception e){
			ar.setMsg("更新用户失败(" + e.getMessage() + ")");
		}
		ResponseUtil.returnJson(response, ar);
	}
	
	@RequestMapping("/detail/{id}")
	public ModelAndView detail(@PathVariable long id, HttpServletRequest request, HttpSession session, HttpServletResponse response, Map<String,Object> model){
		try {
			User user = userService.findById(id);
			if(user.getTwoInchPhotos() == null || user.getTwoInchPhotos().endsWith("default_headpic.png")){
				user.setTwoInchPhotos("view/images/default_headpic.png");
			}
			user.setPassword(null);
			Set<Role> roles = user.getRoles();
			if(roles.size() != 0)
			{
				for(Role r : roles)
				{
					r.setPrivileges(null);
					r.setUsers(null);
				}
			}
			model.put("user", JsonUtil.Object2Json(user));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Config.init(request, response, session, model);
		return new ModelAndView("sysMgr/user_detail", model);
	}

	@RequestMapping("/all")
	public void all(HttpServletRequest request, HttpServletResponse response) {
		ActionResult ar = new ActionResult();
		String[] limit = request.getParameterValues("limit");
		String[] pages = request.getParameterValues("page");
		int pagesize = 25;
		int page = 1;
		if(limit.length > 0){
			pagesize = Integer.valueOf(limit[0]);
		}
		if(pages.length > 0){
			page = Integer.valueOf(pages[0]);
		}
		try {
			long total = userService.count();
			List<User> users = userService.list(page, pagesize);
			ar.setSuccess(true);
			UITable table = new UITable();
			table.setTotal(total);
			table.setRows(users);
			ar.setData(table);
		} catch (Exception e) {
			ar.setMsg(e.getMessage());
			e.printStackTrace();
		}
		ResponseUtil.returnJson(response, ar);
	}

	@RequestMapping("/upload_photo")
	public void uploadPhoto(@RequestParam(value = "photo") MultipartFile file,
			HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		ActionResult ar = new ActionResult();
		ar.setSuccess(true);
		ar.setData(SysConfig.UPLOAD + File.separatorChar + file.getOriginalFilename());
		FileUtil.uploadFile(request.getServletContext(), file);
		ResponseUtil.returnJson(response, ar);
	}
	
	@RequestMapping("/login")
	public void login(String userName, String password, HttpServletRequest request, HttpServletResponse response, HttpSession session)
	{
		ActionResult ar = new ActionResult();
		try {
			String p = SimpleCrypto.encrypt(Constants.MANAGER_PASSWORD, password);
			
			User curUser = userService.login(userName, p);
			ar.setSuccess(curUser != null);
			if(curUser != null)
			{
				session.setAttribute(Constants.SESSION_ACCOUNT, curUser);
				session.setAttribute(Constants.SESSION_PRIVILEGES, PrivilegeUtil.mergePrivilege(curUser));
			}
		} catch (Exception e) {
			ar.setMsg(e.getMessage());
		}
		ResponseUtil.returnJson(response, ar);
	}
	
	@RequestMapping("/find_by_dept/{id}")
	public void findByDepartment(@PathVariable long id, HttpServletRequest request, HttpServletResponse response){
		ActionResult ar = new ActionResult();
		try {
			List<User> users = userService.findByDepartment(id);
			ar.setSuccess(true);
			UITable table = new UITable();
			table.setRows(users);
			ar.setData(table);
		} catch (Exception e) {
			ar.setMsg(e.getMessage());
			e.printStackTrace();
		}
		ResponseUtil.returnJson(response, ar);
	}
	
	@RequestMapping("/find_by_dept_flight/{dptId}/{flightId}")
	public void findByDptAndFlight(@PathVariable long dptId, @PathVariable long flightId, HttpServletRequest request, HttpServletResponse response){
		ActionResult ar = new ActionResult();
		try {
			List<User> users = userService.findByDptAndFlight(dptId, flightId);
			ar.setSuccess(true);
			UITable table = new UITable();
			table.setRows(users);
			ar.setData(table);
		} catch (Exception e) {
			ar.setMsg(e.getMessage());
			e.printStackTrace();
		}
		ResponseUtil.returnJson(response, ar);
	}
	
	@RequestMapping("/export/{id}")
	public void export(@PathVariable long id, HttpServletRequest request, HttpServletResponse response){
		User user = null;
		try {
			user = userService.findById(id);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(user != null){
			String basePath = request.getServletContext().getRealPath("/");
			String templatePath = basePath + File.separator + "templates" + File.separator + "report" + File.separator + "word";
			ReportUserModel rum = user.toReportModel();
			ExportUtil.export(response, templatePath, "user_detail.vm", "user", "doc", rum);
		}
	}
}
